/*
 * Copyright 2021-2022 Open Kunlun Technology <https://www.openkunlun.io>
 */

package io.openkunlun.scalarpc.codegen.model

import scala.meta._

/**
 * @author kostas.kougios
 *         Date: 29/08/17
 */
case class PackageEx private (meta: PackageEx.Meta, children: Seq[CodeEx]) extends CodeEx
  with MetaEx.Contains
  with CodeEx.Name[PackageEx] {

  override def tree: Pkg = {
    Pkg(meta.nameTerm, children.map(_.tree.asInstanceOf[Stat]).toList)
  }

  override def name: String = meta.nameTerm.syntax
  override def withName(name: String): PackageEx = {
    copy(meta = meta.copy(nameTerm = Term.Name(name)))
  }

  def traits: Seq[TraitEx] = children.collect {
    case t: TraitEx => t
  }
  def withTrait(tri: TraitEx): PackageEx = withTraits(Seq(tri))
  def withTraits(traits: Seq[TraitEx]): PackageEx = copy(
    children = children ++ traits
  )

  def classes: Seq[ClassEx] = children.collect {
    case c: ClassEx => c
  }
  def withClass(clz: ClassEx): PackageEx = withClasses(Seq(clz))
  def withClasses(classes: Seq[ClassEx]): PackageEx = copy(
    children = children ++ classes
  )

  def objects: Seq[ObjectEx] = children.collect {
    case c: ObjectEx => c
  }
  def withObject(obj: ObjectEx): PackageEx = withObjects(Seq(obj))
  def withObjects(objects: Seq[ObjectEx]): PackageEx = copy(
    children = children ++ objects
  )

  def imports: Seq[ImportEx] = children.collect {
    case i: ImportEx => i
  }
  def withImport(imp: ImportEx): PackageEx = withImports(Seq(imp))
  def withImports(imports: Seq[ImportEx]): PackageEx = copy(
    children = imports ++ children
  )
}

object PackageEx extends PartialParser[PackageEx] {

  case class Meta(tree: Tree, nameTerm: Term.Ref) extends MetaEx

  override def parser: PartialFunction[Tree, PackageEx] = {
    case tree @ q"package $ref { ..$topstats }" =>
      PackageEx(
        Meta(tree, ref),
        topstats.collect(
          ImportEx.parser
            .orElse(TraitEx.parser)
            .orElse(ClassEx.parser)
            .orElse(ObjectEx.parser)
        )
      )
  }
}